
package com.linktco.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.common.comm.HttpDeleteWithBody;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.cert.X509Certificate;
import java.util.Map;

/**
 * Http工具类，返回HttpServletRequest对象和HttpServletResponse对象
 *
 * @author zhangnx
 */
@Slf4j
public class HttpUtil {


    /**
     * 返回一个HttpServletRequest
     *
     * @return request请求体
     */
    public static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }


    /**
     * 返回一个HttpServletResponse
     *
     * @return response响应流
     */
    public static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    /**
     * GET请求
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static JSONObject doGet(String url, Map<String, String> headers) throws Exception {
        HttpGet request = new HttpGet(url);
        JSONObject result = doRequest(request, headers);
        return result;
    }



    @SneakyThrows
    public static JSONObject doPost(String url, Map<String, String> headers, String bodyJson) {
        HttpPost request = new HttpPost(url);
        JSONObject result = doRequest(request, headers, bodyJson);
        return result;
    }


    @SneakyThrows
    public static JSONObject doDelete(String url, Map<String, String> headers) {
        HttpDelete request = new HttpDelete(url);
        JSONObject result = doRequest(request, headers);
        return result;
    }

    @SneakyThrows
    public static JSONObject doDelete(String url, Map<String, String> headers,String bodyJson) {
        HttpDeleteWithBody httpDelete = new HttpDeleteWithBody(url);
        StringEntity se = new StringEntity(bodyJson, "UTF-8");
        se.setContentType("text/json");
        httpDelete.setEntity(se);
        JSONObject result = doRequest(httpDelete, headers);
        return result;
    }



    @SneakyThrows
    public static JSONObject doPut(String url, Map<String, String> headers, String bodyJson) {
        HttpPut request = new HttpPut(url);
        JSONObject result = doRequest(request, headers, bodyJson);
        return result;
    }


    @SneakyThrows
    public static JSONObject doRequest(HttpRequestBase request, Map<String, String> headers) {
        CloseableHttpClient httpclient = HttpClients.createDefault();

        //发送Get请求
        if (U.notEmpty(headers)) {
            headers.forEach((k, v) -> request.addHeader(k, v));
        }
        request.addHeader("Content-Type", "application/json");

        // 设置请求配置，包括超时设置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(10000)
                .setConnectionRequestTimeout(5000)
                .build();

        // 为HttpGet对象设置请求配置
        request.setConfig(requestConfig);

        //获得响应
        CloseableHttpResponse response = httpclient.execute(request);
        //拿到响应体
        HttpEntity httpEntity = response.getEntity();

        //使用工具转换
        String result = EntityUtils.toString(httpEntity, "UTF-8");
        return JSONObject.parseObject(result);
    }


    @SneakyThrows
    public static JSONObject doRequest(HttpEntityEnclosingRequestBase request, Map<String, String> headers, String bodyJson) {
        //信任所有证书，关闭主机名校验
        SSLConnectionSocketFactory ssl = new SSLConnectionSocketFactory(
                SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
                NoopHostnameVerifier.INSTANCE);
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(ssl).build();
        //发送Get请求
        if (U.notEmpty(headers)) {
            headers.forEach((k, v) -> request.addHeader(k, v));
        }
        request.addHeader("Content-Type", "application/json;utf-8");

        request.setEntity(new StringEntity(bodyJson, "utf-8"));
        // 设置请求配置，包括超时设置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(10000)
                .setConnectionRequestTimeout(5000)
                .build();

        // 为HttpGet对象设置请求配置
        request.setConfig(requestConfig);


        //获得响应
        CloseableHttpResponse response = httpclient.execute(request);
        //拿到响应体
        HttpEntity httpEntity = response.getEntity();
        //使用工具转换
        String result = EntityUtils.toString(httpEntity, "UTF-8");
        return JSONObject.parseObject(result);
    }


    public static String  getResult (JSONObject result){
        String path = result.getString("path");
        String status = result.getString("status");
        String message = result.getString("message");
        String error = result.getString("error");
        StringBuilder res = new StringBuilder();
        if (path != null) {
            res.append(path);
        }
        if (status != null) {
            res.append(" ").append(status);
        }
        if (message != null) {
            res.append(" ").append(message);
        }
        if (error != null) {
            res.append(" ").append(error);
        }
        return res.toString();
    }

    /**
     * 直接通过主机忽略HTTPS请求的SSL证书
     * 必须在openConnection之前调用
     */
    public static void ignoreSsl() {
        HostnameVerifier verifier = (s, sslSession) -> true;
        TrustManager[] trustManagers = {new TrustAllTrustManager()};
        SSLContext sc;
        try {
            sc = SSLContext.getInstance("SSL");
            SSLSessionContext ssl = sc.getServerSessionContext();
            ssl.setSessionTimeout(0);
            sc.init(null, trustManagers, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            //激活主机认证
            HttpsURLConnection.setDefaultHostnameVerifier(verifier);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static class TrustAllTrustManager implements TrustManager, X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }


}
